<?php

namespace Frieza\Modules\FakeData\Controllers;

use App\Http\Controllers\Controller;
use App\Pockets\GridDataModel as pGridDataModel;
use Doraemon\cache\Spider;
use Doraemon\model\AdmFakeData;
use Doraemon\model\AdmFakeDataFill;
use Doraemon\model\Member;
use Doraemon\tools\Log;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Form;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;

class FakeDataController extends Controller
{
    public function list(Content $content, Request $request)
    {
        $where = [
            'fake_type' => AdmFakeData::TYPE_FANS,
        ];

        $page = $request->input('page', 1);
        $pageSize = $request->input('per_page', 10);
        $limit = [($page - 1) * $pageSize, $pageSize];

        $rows = AdmFakeData::select('*', [
            'AND' => $where,
            'LIMIT' => $limit,
            "ORDER" => array(
                "id" => "DESC"
            ),
        ]);
        foreach ($rows as $key => $row) {
            $rows[$key]['target'] = json_decode($row['target'], true);

            $rows[$key]['stat'] = Spider::getAll($row['id']);
            Log::debug("机器粉", [$rows[$key]['stat'], $row['id']]);
        }

        $list = [
            'list' => $rows,
            'total' => AdmFakeData::count($where),
        ];

        $gridModel = new pGridDataModel($list['list'], $list['total'], [
            'keyName' => 'circle_id'
        ]);

        $grid = Admin::grid($gridModel, function (Grid $grid) {
            $grid->disableFilter();
            $grid->paginate(10);
            $grid->filter(function (Grid\Filter $filter) {
                $filter->disableIdFilter();
                $filter->equal('circle_name', '圈子名称');
            });

            $grid->disableExport();
            $grid->disableRowSelector();

            $grid->column('id', 'id');
            $grid->column('uid', '目标用户uid')->display(function () {
                return $this->target['uid'];
            });
            $grid->column('fans_num', '涨粉数量')->display(function () {
                return $this->target['fans_num'];
            });
            $grid->column('start_at', '任务开始时间')->display(function () {
                return date('Y-m-d H:i:s', $this->start_at);
            });
            $grid->column('end_at', '任务结束时间')->display(function () {
                return date('Y-m-d H:i:s', $this->end_at);
            });
            $grid->column('status', '任务状态')->display(function () {
                $time = time();
                if ($this->end_at < $time) {
                    return '已结束';
                }
                if ($this->start_at > $time) {
                    return '未开始';
                }
                return '进行中';
            });

            $grid->column('process', '任务进度')->display(function () {
                return '(' . intval($this->stat['follow']) . '/' . (intval($this->target['fans_num']) * count(explode(',', $this->target['uid']))) . ')';
            });
            $grid->column('admin_id', '操作人')->display(function () {
                return Admin::user()->find($this->admin_id)->name;
            });

            $grid->actions(function (Grid\Displayers\Actions $actions) {
                $actions->row->setKeyName('id');
                $actions->disableDelete();
                $actions->disableEdit();

                $time = time();
                if ($time < $actions->row['end_at']) {//未结束
                    $actions->append('<a href="/admin/FakeData/stop/' . $actions->row->id . '"class="fa fa-eye">停止</a>');
                }
            });
        });

        return $content
            ->header('涨粉任务')
            ->breadcrumb(['text' => '涨粉任务'])
            ->body($grid);
    }


    public function create(Content $content, $fakeId = 0)
    {
        Log::debug("编辑/创建任务", compact('fakeId'));
        return $content
            ->header('新建涨粉任务')
            ->breadcrumb(['text' => '涨粉任务', 'url' => '/admin/FakeData'], ['text' => '新建涨粉任务'])
            ->row($this->_formatForm($fakeId));
    }

    public function stop($fakeId)
    {
        $fakeId = intval($fakeId);
        if (empty($fakeId)) {
            $error = new MessageBag([
                'title' => "任务ID不合法",
            ]);
            return back()->with(compact('error'))->withInput();
        }

        $timestamp = time();
        try {
            $stmt = AdmFakeData::update([
                'status' => AdmFakeData::STATUS_DEL,
                'end_at' => $timestamp,
                'updatetime' => $timestamp,
            ], [
                'id' => $fakeId,
            ]);
            Log::debug('停止执行涨粉任务', [$stmt->rowCount()]);

            // 删除填充记录表
            AdmFakeDataFill::update([
                'fake_status' => AdmFakeDataFill::STATUS_DEL,
            ], [
                'fake_id' => $fakeId,
                'fake_status' => AdmFakeDataFill::STATUS_NORMAL,
            ]);

            Log::debug("任务已停止", compact('fakeId'));

            return redirect(url("/admin/FakeData"));
        } catch (\Exception $e) {
            $error = new MessageBag([
                'title' => $e->getMessage()
            ]);
            return back()->with(compact('error'))->withInput();
        }
    }

    public function save(Request $request)
    {
        try {
            $params = $request->all();
            $fans_num = intval($params['fans_num']);
            $start_time = strtotime($params['start_at']);
            $end_time = strtotime($params['end_at']);

            if ($fans_num > 1000) {
                $error = new MessageBag([
                    'title' => "粉丝数不能超过1000",
                ]);
                return back()->with(compact('error'))->withInput();
            }


            $aUid = explode(',', $params['uid']);
            if (empty($aUid)) {
                $error = new MessageBag([
                    'title' => "用户uid不合法1",
                ]);
                return back()->with(compact('error'))->withInput();
            }

            if (count($aUid) > 100) {
                $error = new MessageBag([
                    'title' => "一次最多指定100个用户",
                ]);
                return back()->with(compact('error'))->withInput();
            }

            $aUsers = Member::select('uid', [
                'uid' => $aUid,
            ]);
            if (empty($aUsers) || count($aUsers) != count($aUid)) {
                Log::error("用户uid不合法2", compact('aUsers', 'aUid'));
                $error = new MessageBag([
                    'title' => "用户uid不合法2",
                ]);
                return back()->with(compact('error'))->withInput();
            }

            if ($start_time < time()) {
                $error = new MessageBag([
                    'title' => "开始时间不合法",
                ]);
                return back()->with(compact('error'))->withInput();
            }
            if ($start_time >= $end_time) {
                $error = new MessageBag([
                    'title' => "结束时间不合法",
                ]);
                return back()->with(compact('error'))->withInput();
            }

            if (($end_time - $start_time) / (24 * 3600) > 30) {
                $error = new MessageBag([
                    'title' => "不支持30天以上的任务",
                ]);
                return back()->with(compact('error'))->withInput();
            }
            
            //默认涨粉时段为9:00-21:00，非此时段不涨粉
            $second_count = 0;
            for ($i = $start_time; $i < $end_time; $i++) {
                $hour = date('H', $i);
                if ($hour >= 9 && $hour < 21) {
                    $second_count++;
                }
            }
            $interval_time = $second_count / $fans_num;
            Log::debug("涨粉调试", compact('second_count', 'interval_time', 'start_time', 'end_time'));

            AdmFakeData::insert([
                'admin_id' => Admin::user()->id,
                'fake_type' => AdmFakeData::TYPE_FANS,
                'target' => json_encode([
                    'uid' => $params['uid'],
                    "fans_num" => $fans_num,
                ], JSON_UNESCAPED_UNICODE),
                'start_at' => $start_time,
                'end_at' => $end_time,
                'status' => AdmFakeData::STATUS_NORMAL,
            ]);
            $fake_id = AdmFakeData::id();

            foreach ($aUid as $uid) {
                $uid = intval($uid);
                if ($uid <= 0) {
                    continue;
                }
                $fake_time = $start_time;
                for ($i = 0; $i < $fans_num; $i++) {
                    $fake_hour = date('H', $fake_time);
                    if ($fake_hour < 9) {//跳转到第9点
                        $fake_time += (9 - $fake_hour) * 3600;
                    }
                    if ($fake_hour >= 21) {//跳转到第二天
                        $delta_seconds = $fake_time - strtotime(date('Y-m-d 21:00:00', $fake_time));
                        $fake_time = strtotime('tomorrow', $fake_time) + 3600 * 9 + $delta_seconds;
                    }

                    $fake_info = [];
                    $fake_info['fake_id'] = $fake_id;
                    $fake_info['obj_type'] = 'user';
                    $fake_info['obj_id'] = $uid;
                    $fake_info['fake_type'] = 'follow';
                    $fake_info['fake_time'] = $fake_time + rand(0, min($interval_time, 3600));
                    $fake_info['fake_status'] = AdmFakeDataFill::STATUS_NORMAL;
                    $fake_info['addtime'] = time();

                    AdmFakeDataFill::insert($fake_info);

                    $fake_time += $interval_time;
                }
            }

            return redirect(url("/admin/FakeData"));
        } catch (\Exception $e) {
            $error = new MessageBag([
                'title' => $e->getMessage()
            ]);
            return back()->with(compact('error'))->withInput();
        }
    }

    private function _formatForm($fakeId)
    {
        $info = [];
        if ($fakeId) {
            $info = AdmFakeData::get('*', ['id' => $fakeId]);
            if ($info['fake_type'] != 1) {
                return '数据异常';
            }
            if (time() >= $info['start_at'] || time() >= $info['end_at']) {
                return '该任务不可以编辑';
            }
        }

        $fill = [];
        if ($info) {
            $target = json_decode($info['target'], true);
            $fill = [
                'id' => $info['id'],
                'uid' => $target['uid'],
                'fans_num' => $target['fans_num'],
                'start_at' => date('Y-m-d H:i:s', $info['start_at']),
                'end_at' => date('Y-m-d H:i:s', $info['end_at']),
            ];
        }
        $form = new Form($fill);
        $form->hidden('id', '圈子id');
        $form->text('uid', '目标用户uid')->required()->placeholder('输入uid，多个uid以英文逗号分隔');
        $form->text('fans_num', '目标涨粉量')->required()->placeholder('输入数字');
        $form->datetime('start_at', '任务开始时间')->format('YYYY-MM-DD HH:mm:ss')->default('');
        $form->datetime('end_at', '任务结束时间')->format('YYYY-MM-DD HH:mm:ss')->default('');

        $form->action('/admin/FakeData/save');

        return $form->render();
    }
}
